﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using System.Data.Services.Client;
using Social_Photos.Social_Photos_Services;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Tasks;
using Microsoft.Xna.Framework.Media;
using System.IO.IsolatedStorage;
using System.IO;
using Microsoft.Phone;
using System.Collections.Specialized;
using System.Net;
using System.IO;
using System.Device.Location;
using System.Text;
using System.Xml.Linq;

namespace Social_Photos
{
    public partial class MainPage : PhoneApplicationPage
    {     
        private GeoCoordinateWatcher _watcher;
     
        CameraCaptureTask cameraCaptureTask;
        public Photo currentPhoto;
        public bool chooserCancelled;
        
        private byte[] _imageBytes;
        private string flag;
        string filename;
        string _filename;
        int _id;
        int userID;
        short? _like;
        short? _dislike;
        string Latitude;
        string Longitude;

        double? _latitude;
        double? _longitude;

        static string serviceUriString = UrlConfig.SERVICE_URI_STRING;

        // Declare the service root URI.
        private Uri svcRootUri =
            new Uri(serviceUriString, UriKind.Absolute);

        // Declare our private binding collection.
        private DataServiceCollection<Photo> _topphotos;

        // Declare the DataServiceContext as private.
        private SocialPhotoModelContainer _topcontext;

        // Declare our private binding collection.
        private DataServiceCollection<Photo> _myphotos;

        // Declare the DataServiceContext as private.
        private SocialPhotoModelContainer _mycontext;

        public bool IsDataLoaded { get; private set; }

        // Constructor
        public MainPage()
        {
            InitializeComponent();
            cameraCaptureTask = new CameraCaptureTask();
            cameraCaptureTask.Completed += new EventHandler<PhotoResult>(cameraCaptureTask_Completed);
           
            _watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
            _watcher.MovementThreshold = 10; // 10 meters
            _watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(OnStatusChanged);
            _watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(OnPositionChanged);
            _watcher.Start();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            string userIdAsString = this.NavigationContext.QueryString["userID"];
            userID = int.Parse(userIdAsString);

            this.LoadTopRated();
            this.LoadMyPhoto();
        }

        private void LoadTopRated()
        {
            // Display the progress bar.
            this.requestProgress.Visibility = Visibility.Visible;
            this.requestProgress.IsIndeterminate = true;

            // Instantiate the context and binding collection.
            _topcontext = new SocialPhotoModelContainer(svcRootUri);
            _topphotos = new DataServiceCollection<Photo>(_topcontext);

            // Load the data from the Photo feed.
            _topphotos.LoadAsync(new Uri(UrlConfig.GET_TOP_LIKE, UriKind.Relative));

            // Register for the LoadCompleted event to turn off the progress bar.
            _topphotos.LoadCompleted +=
                new EventHandler<LoadCompletedEventArgs>(Photos_LoadCompleted);

        }

        void Photos_LoadCompleted(object sender, System.Data.Services.Client.LoadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                // Make sure that we load all pages of the Photo feed.
                if (_topphotos.Continuation != null)
                {
                    // Request the next page from the data service.
                    _topphotos.LoadNextPartialSetAsync();
                }
                else
                {
                    List<TopPhotosListBox> photoList = new List<TopPhotosListBox>();
                    for (int i = 0; i < _topphotos.Count; i++)
                    {
                        Photo info = _topphotos[i];
                        Uri uri = new Uri(UrlConfig.GET_THUMBNAIL + info.FileName);
                        photoList.Add(new TopPhotosListBox(uri.ToString(),info.FileName,info.Id,info.Likes,info.Dislikes,info.Latitude,info.Longitude));
                    }
                    //Put image
                    TopRated.ItemsSource = photoList;
                    this.LoadMyPhoto();

                }
                this.requestProgress.Visibility = Visibility.Collapsed;
                this.requestProgress.IsIndeterminate = false;
            }
            else
            {
                if (MessageBox.Show(e.Error.Message, "Retry request?",
                    MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    //    this.LoadData();
                }
            }
        }

        private void LoadMyPhoto()
        {
            // Display the progress bar.
            this.requestProgress.Visibility = Visibility.Visible;
            this.requestProgress.IsIndeterminate = true;

          //  int id = 1;
            // Instantiate the context and binding collection.
            _mycontext = new SocialPhotoModelContainer(svcRootUri);
            _myphotos = new DataServiceCollection<Photo>(_mycontext);

            // Load the data from the Photo feed.
            _myphotos.LoadAsync(new Uri(UrlConfig.PHOTOS_BY_USER_ID_SERVICE_STRING + userID, UriKind.Relative));

            // Register for the LoadCompleted event to turn off the progress bar.
            _myphotos.LoadCompleted +=
                new EventHandler<LoadCompletedEventArgs>(MyPhotos_LoadCompleted);

        }

        void MyPhotos_LoadCompleted(object sender, System.Data.Services.Client.LoadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                // Make sure that we load all pages of the Customers feed.
                if (_myphotos.Continuation != null)
                {
                    // Request the next page from the data service.
                    _myphotos.LoadNextPartialSetAsync();
                }
                else
                {
                    List<MyPhotoListBox> photoList = new List<MyPhotoListBox>();
                    for (int i = 0; i < _myphotos.Count; i++)
                    {
                        Photo info = _myphotos[i];
                        Uri uri = new Uri(UrlConfig.GET_THUMBNAIL + info.FileName);
                        photoList.Add(new MyPhotoListBox(uri.ToString(), info.FileName, info.Id, info.Likes, info.Dislikes, info.Latitude, info.Longitude));
                    }
                    //put image
                    MyPhoto.ItemsSource = photoList;

                }
                this.requestProgress.Visibility = Visibility.Collapsed;
                this.requestProgress.IsIndeterminate = false;
            }
            else
            {
                if (MessageBox.Show(e.Error.Message, "Retry request?",
                    MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    //    this.LoadData();
                }
            }
        }


        private void OnSelectionTopPhotos(object sender, SelectionChangedEventArgs e)
        {
           
                var selector = (Selector)sender;
                if (selector.SelectedIndex == -1)
                {
                    return;
                }

                //get Id

                foreach (TopPhotosListBox photo in e.AddedItems)
                {
                    _filename = photo.filename;
                    _id = photo.id;
                    _like = photo.like;
                    _dislike = photo.dislike;
                    _latitude = photo.latitude;
                    _longitude = photo.longitude;
                    
                }
                if (_latitude == null || _longitude == null)
                {
                    _latitude = 21.02698836791695;
                    _longitude = 105.8536148071289;
                }

                // Navigate to the details page for the selected item.
                this.NavigationService.Navigate(
                    new Uri("/PhotoDetails.xaml?filename="
                        + _filename + "&PhotoId=" + _id + "&like=" + _like + "&dislike=" + _dislike + "&latitude=" + _latitude + "&longitude=" + _longitude + "&userID=" + userID, UriKind.Relative));

                selector.SelectedIndex = -1;
            
        }

        private void OnSelectionMyPhotos(object sender, SelectionChangedEventArgs e)
        {

            var selector = (Selector)sender;
            if (selector.SelectedIndex == -1)
            {
                return;
            }

            //get Id

            foreach (MyPhotoListBox photo in e.AddedItems)
            {
                _filename = photo.filename;
                _id = photo.id;
                _like = photo.like;
                _dislike = photo.dislike;
                _latitude = photo.latitude;
                _longitude = photo.longitude;
                
                
            }
            if (_latitude == null || _longitude == null)
            {
                _latitude = 21.02698836791695;
                _longitude = 105.8536148071289;
            }
            // Navigate to the details page for the selected item.
            this.NavigationService.Navigate(
                new Uri("/PhotoDetails.xaml?filename="
                    + _filename + "&PhotoId=" + _id + "&like=" + _like + "&dislike=" + _dislike + "&latitude=" + _latitude + "&longitude=" + _longitude + "&userID=" + userID, UriKind.Relative));
            
            selector.SelectedIndex = -1;

        }


        private void btnCapture_Click(object sender, EventArgs e)
        {
            flag = "capture";
        
            Photo newPhoto = Photo.CreatePhoto(0,string.Empty, string.Empty);
            // Add the new photo to the tracking collection.
            _myphotos.Add(newPhoto);
            cameraCaptureTask.Show();
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            // Reload the data from the data service.
            this.LoadTopRated();
            this.LoadMyPhoto();
        }

        /*------------------------------UPLOAD - SAVE PHOTO--------------------------------*/

        private void cameraCaptureTask_Completed(object sender, PhotoResult e)
        {
            // Get back the last PhotoInfo in the collection, which we just added.
            //  currentPhoto = App.ViewModel.Photos[App.ViewModel.Photos.Count - 1];

            if (e.TaskResult == TaskResult.OK)
            {
                //StartLocationService(GeoPositionAccuracy.High);
               // MessageBox.Show(Latitude);
                BitmapImage bitmap;

                DateTime currentTime = DateTime.Now;
                string day = currentTime.Day.ToString();
                string month = currentTime.Month.ToString();
                string year = currentTime.Year.ToString();
                string hour = currentTime.Hour.ToString();
                string minute = currentTime.Minute.ToString();
                string second = currentTime.Second.ToString();

                filename = day + month + year + hour + minute + second;

                _imageBytes = new byte[(int)e.ChosenPhoto.Length];
                e.ChosenPhoto.Read(_imageBytes, 0, _imageBytes.Length);
                e.ChosenPhoto.Seek(0, System.IO.SeekOrigin.Begin);

                bitmap = new BitmapImage();
                bitmap.SetSource(e.ChosenPhoto);
                e.ChosenPhoto.Position = 0;

                upload();
                
               // MessageBox.Show("Upload Successfully !");
                saveToIsolatedStorage(e.ChosenPhoto, this.filename, "Images");

             //   watcher.Stop();
            }
            else
            {
                // Assume that the select photo operation was cancelled,
                // remove the added PhotoInfo and navigate back to the main page.
               // App.ViewModel.Photos.Remove(currentPhoto);
                chooserCancelled = true;
            }
            this.LoadTopRated();
            this.LoadMyPhoto();
        }

        

        /*---------------------------------------Save to Isolated---------------------------------------------*/
        private void saveToIsolatedStorage(Stream imageStream, string fileName, string imageFolder)
        {
            var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
            if (!isoFile.DirectoryExists(imageFolder))
            {
                isoFile.CreateDirectory(imageFolder);
            }
            if (isoFile.FileExists(this.filename))
            {
                isoFile.DeleteFile(this.filename);
            }

            string filePath = Path.Combine(imageFolder, fileName);
            using (var stream = isoFile.CreateFile(filePath))
            {
                BitmapImage bitmap = new BitmapImage();
                bitmap.SetSource(imageStream);

                WriteableBitmap wb = new WriteableBitmap(bitmap);
                wb.SaveJpeg(stream, wb.PixelWidth, wb.PixelHeight, 0, 85);
                // stream.Close();
            }

            using (var _imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
            {

                MediaLibrary library = new MediaLibrary();
                library.SavePicture(this.filename, _imageStream);
            }
        }
        /*---------------------------------------Upload-------------------------------------------*/
        public void upload()
        {
           // MessageBox.Show(Longtitude + "------" + Latitude);
            string upload_url = UrlConfig.UPLOAD_PHOTO;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(upload_url);
            request.ContentType = "application/x-www-form-urlencoded";
            request.Method = "POST";
            request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
        }

        private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            try
            {

                HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
                string encoding = "iso-8859-1";
                Stream postStream = request.EndGetRequestStream(asynchronousResult);
                string boundary = Guid.NewGuid().ToString();
                request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);

                string header = string.Format("--{0}", boundary);
                string footer = string.Format("--{0}--", boundary);

                StringBuilder contents = new StringBuilder();
                contents.AppendLine(header);

                string fileHeader = String.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"; ", "media", filename + ".jpg");
                string fileData = Encoding.GetEncoding(encoding).GetString(_imageBytes, 0, _imageBytes.Length);

                contents.AppendLine(fileHeader);
                contents.AppendLine(String.Format("Content-Type: {0};", "image/jpeg"));
                contents.AppendLine();
                contents.AppendLine(fileData);

                contents.AppendLine(header);
                contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "latitude"));
                contents.AppendLine();
                contents.AppendLine(Latitude); 
 
                contents.AppendLine(header);
                contents.AppendLine(String.Format("Content-Disposition: form-data;  name=\"{0}\"", "longitude")); 
                contents.AppendLine();
                contents.AppendLine(Longitude);

                contents.AppendLine(header);
                contents.AppendLine(String.Format("Content-Disposition: form-data;  name=\"{0}\"", "userid"));
                contents.AppendLine();
                contents.AppendLine(userID.ToString()); 
           
                contents.AppendLine(footer);

                // Convert the string into a byte array. 
                byte[] byteArray = Encoding.GetEncoding(encoding).GetBytes(contents.ToString());

                // Write to the request stream. 
                postStream.Write(byteArray, 0, byteArray.Length);
                postStream.Close();

                // Start the asynchronous operation to get the response 
                request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
            }
            catch (Exception ex)
            {

            }
        }
        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            try
            {

                HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
                // End the operation 
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                Stream streamResponse = response.GetResponseStream();
                StreamReader streamRead = new StreamReader(streamResponse);
                string responseString = streamRead.ReadToEnd();

                // Close the stream object 
                streamResponse.Close();
                streamRead.Close();

                // Release the HttpWebResponse 
                response.Close();              
            }
            catch (Exception ex)
            {

            }
        }


        /*----------------------------------------Location Service-------------------------------------------*/

        void OnStatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            if (e.Status == GeoPositionStatus.Disabled)
                MessageBox.Show("The location service is currently turned off.");
            else if (e.Status == GeoPositionStatus.NoData)
                MessageBox.Show("No location data is currently available. Try again later.");
        }

        void OnPositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            var epl = e.Position.Location;
            Latitude = epl.Latitude.ToString("0.000");
            Longitude = epl.Longitude.ToString("0.000");

        }


        private void btnChooseImage_Click(object sender, EventArgs e)
        {

            this.NavigationService.Navigate(
                        new Uri("/UploadPhoto.xaml?userID=" + userID, UriKind.Relative));
        }
    }
}